package cn.com.surker.system.service.impl;

import cn.com.surker.enums.weight.WeightCarTypeEnum;
import cn.com.surker.enums.weight.WeightTypeEnum;
import cn.com.surker.material.dao.MainMaterialWeightDao;
import cn.com.surker.material.entity.MainMaterialWeight;
import cn.com.surker.production.dao.IndentDispatchDao;
import cn.com.surker.production.dao.ProductionIndentDao;
import cn.com.surker.production.dao.ProductionInvoiceDao;
import cn.com.surker.production.dao.TranConCarDao;
import cn.com.surker.production.entity.vo.TranConCarVo;
import cn.com.surker.redis.RedisUtils;
import cn.com.surker.system.service.HomeService;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.ReportDateUtils;
import cn.com.surker.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author lucky
 * @create 2025年01月22 21:06
 * @desc
 */
@Service
public class HomeServiceImpl implements HomeService {

    @Resource
    private MainMaterialWeightDao materialWeightDao;
    @Value("${erp.org.id}")
    protected String erpOrgId;
    @Resource
    private TranConCarDao tranConCarDao;
    @Resource
    private ProductionInvoiceDao invoiceDao;
    @Resource
    private IndentDispatchDao indentDispatchDao;
    @Resource
    private ProductionIndentDao indentDao;
    @Resource
    private RedisUtils redisUtils;
    @Value("${erp.datasource.erp.db}")
    private String erpDb;

    public static void main(String[] args){
        System.out.println(ReportDateUtils.getMonthFirstDay());
        System.out.println(DateUtil.differentHour(DateUtil.convertDate(ReportDateUtils.getToday() + " 07:30:00"), new Date()));
    }

    /**
     * 加载材料/搅拌车辆信息
     * @param type 0材料车 1搅拌车
     * @return
     */
    public List<MainMaterialWeight> loadWeightCar(String startTime, String endTime,Integer type) {
        if (StringUtils.isNull(type))
            type = 0;
        if (StringUtils.isNull(startTime)) {
            startTime = ReportDateUtils.getToday() + " 08:30:00";
        }

        QueryWrapper<MainMaterialWeight> query = new QueryWrapper<>();
        query.eq("status", 0);
        query.ge("in_time", startTime);
        query.orderByDesc("id");
        if (type == 0) {
            Integer[] types = {WeightCarTypeEnum.MATERIAL.getCode(), WeightCarTypeEnum.TRAN.getCode()};
            query.in("car_type", types);
        } else {
            Integer[] types = {WeightCarTypeEnum.WATER.getCode(), WeightCarTypeEnum.XIMING.getCode(), WeightCarTypeEnum.PULL.getCode()};
            query.in("car_type", types);
        }
        query.orderByDesc("id");
        List<MainMaterialWeight> weightList = materialWeightDao.selectList(query);
        if (weightList != null && weightList.size() > 0) {
            List<MainMaterialWeight> resultList = new ArrayList<>();
            if (type == 0) {
                if (weightList.size() < 10)
                    return weightList;
                for (int i = 0; i < 10; i++) {
                    Random rand = new Random();
                    int randomNumber = rand.nextInt(weightList.size());
                    MainMaterialWeight weight = weightList.get(randomNumber);
                    resultList.add(weight);
                    weightList.remove(randomNumber);
                }
                return resultList;
            } else {
                Map<String, String> carMap = new HashMap<>();
                if (!StringUtils.isNull(erpOrgId)) {
                    Long orgId = StringUtils.convertLong(erpOrgId);
                    List<TranConCarVo> carVoList = tranConCarDao.findOrgCarAll(orgId);
                    if (carVoList != null && carVoList.size() > 0){
                        for (int i = 0; i < carVoList.size();i++) {
                            TranConCarVo carVo = carVoList.get(i);
                            carMap.put(carVo.getCarNo(), carVo.getCode());
                        }
                    }
                }
                if (weightList.size() < 10)
                    return weightList;
                for (int i = 0; i < 10; i++) {
                    Random rand = new Random();
                    int randomNumber = rand.nextInt(weightList.size());
                    MainMaterialWeight weight = weightList.get(randomNumber);
                    if (carMap.containsKey(weight.getCarNo())) {
                        weight.setCarNo(carMap.get(weight.getCarNo()) + "|" + weight.getCarNo());
                    }
                    resultList.add(weight);
                    weightList.remove(randomNumber);
                }
                return resultList;
            }
        }
        return null;
    }
    /**
     * 查询首页抬头
     * @return planStere 计划量 dayStere 日产量 monthStere 月产量 yearStere年产量
     */
    public Map<String, Object> loadTitleVal(String startTime, String endTime) {
        Date nowDate = new Date();
        String key = "ERP_HOME_TITLE_KEY";
        Map<String, Object> map = new HashMap<>();
        if (redisUtils.exists(key)) {
            String json = (String) redisUtils.get(key);
            map = StringUtils.aliConvertMap(json);
            return map;
        }
        if (StringUtils.isNull(startTime)) {
            startTime = ReportDateUtils.getToday() + " 08:30:00";
        }
        if (StringUtils.isNull(endTime)) {
            endTime = DateUtil.convertString(nowDate);
        }

        String monthStartTime = ReportDateUtils.getMonthFirstDay() + " 08:30:00";
        String yearStartTime = ReportDateUtils.getYearFirstDay() + " 08:30:00";
        Double planStere = indentDao.findPlanStere(startTime, endTime);
        Double dayStere = indentDispatchDao.queryCloudTimeSendStere(erpDb,startTime, endTime);
        Double monthStere = indentDispatchDao.queryCloudTimeSendStere(erpDb,monthStartTime, endTime);
        Double yearStere = indentDispatchDao.queryCloudTimeSendStere(erpDb,yearStartTime, endTime);
        if (StringUtils.isNull(planStere))
            planStere = 0.0;
        else
            planStere = StringUtils.formatDouble(planStere, 1);
        if (StringUtils.isNull(dayStere))
            dayStere = 0.0;
        else
            dayStere = StringUtils.formatDouble(dayStere, 1);
        if (StringUtils.isNull(monthStere))
            monthStere = 0.0;
        else
            monthStere = StringUtils.formatDouble(monthStere, 1);
        if (StringUtils.isNull(yearStere))
            yearStere = 0.0;
        else
            yearStere = StringUtils.formatDouble(yearStere, 1);
        map.put("planStere", planStere);
        map.put("dayStere", dayStere);
        map.put("monthStere", monthStere);
        map.put("yearStere", yearStere);
        String json = StringUtils.aliConvertJSONObject(map);
        redisUtils.set(key, json, 150l);
        return map;
    }

    /**
     * 查询发货量趋势、生产量图表
     * @return sendStere 发货量 pumpStere 泵送量 signStere 签收量 proStere 生产量 hours 小时数
     */
    public List<Map<String, Object>> loadProTrend(String startTime, String endTime) {
        Date nowDate = new Date();
        if (StringUtils.isNull(startTime)) {
            startTime = ReportDateUtils.getToday() + " 08:30:00";
        }
        if (StringUtils.isNull(endTime)) {
            endTime = DateUtil.convertString(nowDate);
        }
        String key = "ERP_HOME_TREND_KEY";
        if (redisUtils.exists(key)) {
            String json = (String) redisUtils.get(key);
            List<Map<String, Object>> list = StringUtils.convertListMap(json);
            return list;
        }
        //hours hours 小时 proStere 生产量
        List<Map<String, Object>> proList = indentDispatchDao.findHoursProStere(startTime, endTime);
        //hours 小时数 pumpStere 泵送量 operateStere 转料量
        List<Map<String, Object>> pumpList = invoiceDao.findHoursPumpStere(erpDb, startTime, endTime);
        //hours 小时数 sendStere 发货量 signStere 签收
        List<Map<String, Object>> sendList = invoiceDao.findHoursSendStere(erpDb, startTime, endTime);

        Map<Integer, Map<String, Object>> hoursMap = new LinkedHashMap<>();
        for (int i = 0; i < 24; i++) {
            if (i % 2 == 0) {
                Map<String, Object> initMap = new HashMap<>();
                initMap.put("sendStere", 0.0);
                initMap.put("pumpStere", 0.0);
                initMap.put("signStere", 0.0);
                initMap.put("proStere", 0.0);
                initMap.put("hours", i);
                hoursMap.put(i, initMap);
            } else {
                continue;
            }
        }
        if (sendList != null && sendList.size() > 0) {
            for (int i = 0; i < sendList.size(); i++) {
                Map<String, Object> temp = sendList.get(i);
                Integer hours = StringUtils.convertInteger(temp.get("hours"));
                Double tempSendStere = StringUtils.convertDouble(temp.get("sendStere"));
                Double tempSignStere = StringUtils.convertDouble(temp.get("signStere"));
                if (hours % 2 == 1) {
                    hours = hours -1;
                }
                Map<String, Object> initMap = hoursMap.get(hours);
                Double sendStere = StringUtils.formatDouble(StringUtils.convertDouble(initMap.get("sendStere")) + tempSendStere, 1);
                Double signStere = StringUtils.formatDouble(StringUtils.convertDouble(initMap.get("signStere")) + tempSignStere, 1);
                initMap.put("sendStere", sendStere);
                initMap.put("signStere", signStere);
                hoursMap.put(hours, initMap);
            }
        }
        if (proList != null && proList.size() > 0) {
            for (int i = 0; i < proList.size(); i++) {
                Map<String, Object> temp = proList.get(i);
                Integer hours = StringUtils.convertInteger(temp.get("hours"));
                Double tempProStere = StringUtils.convertDouble(temp.get("proStere"));
                if (hours % 2 == 1) {
                    hours = hours -1;
                }
                Map<String, Object> initMap = hoursMap.get(hours);
                Double proStere = StringUtils.formatDouble(StringUtils.convertDouble(initMap.get("proStere")) + tempProStere, 1);
                initMap.put("proStere", proStere);
                hoursMap.put(hours, initMap);
            }
        }
        if (pumpList != null && pumpList.size() > 0) {
            for (int i = 0; i < pumpList.size(); i++) {
                Map<String, Object> temp = pumpList.get(i);
                Integer hours = StringUtils.convertInteger(temp.get("hours"));
                Double tempPumpStere = StringUtils.convertDouble(temp.get("pumpStere"));
                Double operateStere = StringUtils.convertDouble(temp.get("operateStere"));
                tempPumpStere = tempPumpStere - operateStere;
                if (tempPumpStere < 0)
                    tempPumpStere = 0.0;
                if (hours % 2 == 1) {
                    hours = hours -1;
                }
                Map<String, Object> initMap = hoursMap.get(hours);
                Double pumpStere = StringUtils.formatDouble(StringUtils.convertDouble(initMap.get("pumpStere")) + tempPumpStere, 1);
                initMap.put("pumpStere", pumpStere);
                hoursMap.put(hours, initMap);
            }
        }
        List<Map<String, Object>> list = new ArrayList<>();
        for (Integer hoursKey : hoursMap.keySet()) {
            list.add(hoursMap.get(hoursKey));
        }
        String json = StringUtils.aliConvertJSONArray(list).toString();
        redisUtils.set(key, json, 150l);
        return list;
    }

    /**
     * 查询生产线top榜
     * @return
     */
    public List<Map<String, Object>> loadLineTop(String startTime, String endTime) {
        Date nowDate = new Date();
        Double hoursStere = 180.0;
        if (StringUtils.isNull(startTime)) {
            startTime = ReportDateUtils.getToday() + " 08:30:00";
        }
        if (StringUtils.isNull(endTime)) {
            endTime = DateUtil.convertString(nowDate);
        }
        String key = "ERP_HOME_LINE_TOP_KEY";
        if (redisUtils.exists(key)) {
            String json = (String) redisUtils.get(key);
            List<Map<String, Object>> list = StringUtils.convertListMap(json);
            return list;
        }
        Integer hours = Math.abs(DateUtil.differentHour(DateUtil.convertDate(ReportDateUtils.getToday() + " 07:30:00"), new Date()));
        if (hours > 0)
            hoursStere = hoursStere * hours;
        if (hoursStere < 1)
            hoursStere = 180.0;
        List<Map<String, Object>> lineList = invoiceDao.findLineProStere(startTime, endTime);
        if (lineList == null || lineList.size() == 0)
            return null;
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < lineList.size(); i++) {
            Map<String, Object> temp = lineList.get(i);
            Double proStere = StringUtils.convertDouble(temp.get("proStere"));
            Double rate = 0.0;
            if (proStere > 0)
                rate = StringUtils.formatDouble((proStere / hoursStere) * 100, 1);
            if (rate.intValue() > 100)
                rate = 100.0;
            temp.put("rate", rate);
            list.add(temp);
        }

        String json = StringUtils.aliConvertJSONArray(list).toString();
        redisUtils.set(key, json, 150l);
        return list;
    }

    /**
     * 查询车辆top榜
     * @return
     */
    public List<Map<String, Object>> loadCarTop(String startTime, String endTime) {
        Date nowDate = new Date();
        if (StringUtils.isNull(startTime)) {
            startTime = ReportDateUtils.getToday() + " 08:30:00";
        }
        if (StringUtils.isNull(endTime)) {
            endTime = DateUtil.convertString(nowDate);
        }
        String key = "ERP_HOME_CAR_TOP_KEY";
        if (redisUtils.exists(key)) {
            String json = (String) redisUtils.get(key);
            List<Map<String, Object>> list = StringUtils.convertListMap(json);
            return list;
        }
        List<Map<String, Object>> list = invoiceDao.findTopCarStere(startTime, endTime);
        if (list == null || list.size() == 0)
            return null;

        String json = StringUtils.aliConvertJSONArray(list).toString();
        redisUtils.set(key, json, 150l);
        return list;
    }

    /**
     * 查询项目进度
     * @return
     */
    public List<Map<String, Object>> loadConProgress(String startTime, String endTime) {
        Date nowDate = new Date();
        if (StringUtils.isNull(startTime)) {
            startTime = ReportDateUtils.getToday() + " 08:30:00";
        }
        if (StringUtils.isNull(endTime)) {
            endTime = DateUtil.convertString(nowDate);
        }
        String key = "ERP_HOME_CON_PROGRESS_KEY";
        if (redisUtils.exists(key)) {
            String json = (String) redisUtils.get(key);
            List<Map<String, Object>> list = StringUtils.convertListMap(json);
            return list;
        }
        List<Map<String, Object>> progressList = invoiceDao.findContractProgress(startTime, endTime);
        if (progressList == null || progressList.size() == 0)
            return null;
        List<Map<String, Object>> list = new ArrayList<>();
        if (progressList.size() < 5) {
            list = progressList;
        } else {
            for (int i = 0; i < 5; i++) {
                Random rand = new Random();
                int randomNumber = rand.nextInt(progressList.size());
                Map<String, Object> map = progressList.get(randomNumber);
                String openTime = StringUtils.convertString(map.get("openTime"));
                Integer type = StringUtils.convertInteger(map.get("type"));
                Integer isDelay = 0;//是否延期开盘 0未延期 1 已验签
                if (!StringUtils.isNull(openTime) && type == 0) {
                    Date openDate = DateUtil.convertDate(openTime);
                    if (nowDate.getTime() > openDate.getTime())
                        isDelay = 1;//延期开盘
                }
                map.put("isDelay", isDelay);
                list.add(map);
                progressList.remove(randomNumber);
            }
        }

        String json = StringUtils.aliConvertJSONArray(list).toString();
        redisUtils.set(key, json, 150l);
        return list;
    }

    /**
     * 查询强度生产占比
     * @return
     */
    public List<Map<String, Object>> loadStrengthProportion(String startTime, String endTime) {
        Date nowDate = new Date();
        if (StringUtils.isNull(startTime)) {
            startTime = ReportDateUtils.getToday() + " 08:30:00";
        }
        if (StringUtils.isNull(endTime)) {
            endTime = DateUtil.convertString(nowDate);
        }
        String key = "ERP_HOME_STRENGTH_PROPORTION_KEY";
        if (redisUtils.exists(key)) {
            String json = (String) redisUtils.get(key);
            List<Map<String, Object>> list = StringUtils.convertListMap(json);
            return list;
        }
        List<Map<String, Object>> list = invoiceDao.findStrengthProportion(startTime, endTime);
        if (list == null || list.size() == 0)
            return null;

        String json = StringUtils.aliConvertJSONArray(list).toString();
        redisUtils.set(key, json, 150l);
        return list;
    }
}
